// arduino_like.c
#include "Arduino.h"
#include "pin_map.h"
#include "stm32f10x.h"
#include "stm32f10x_tim.h"

// 外设初始化标志
static uint8_t pwm_initialized = 0;

/**
 * @brief 初始化引脚模式
 */
/**
 * @brief 设置引脚模式（支持输入、输出、复用等）
 */
void pinMode(GPIO_PinName pin, PinMode mode)
{
    if (pin >= PIN_COUNT || pin == GPIO_PIN_NONE) return;

    const PinMap *p = &pin_map[pin];

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = p->pin;

    if (p->port == GPIOA) {
				RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		} else if (p->port == GPIOB) {
				RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
		} else if (p->port == GPIOC) {
				RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
		} else if (p->port == GPIOD) {
				RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
		}
    switch (mode) {
        case INPUT:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            break;

        case INPUT_ANALOG:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
            break;

        case INPUT_PULLUP:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(p->port, &GPIO_InitStructure); 
            return;  // 提前返回，避免重复 Init

        case INPUT_PULLDOWN:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(p->port, &GPIO_InitStructure);
            return;

        case OUTPUT:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            break;

        case OUTPUT_OD:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            break;

        case OUTPUT_AF_PP:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            break;

        case OUTPUT_AF_OD:
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            break;

        default:
            return;
    }

    GPIO_Init(p->port, &GPIO_InitStructure);
}


/**
 * @brief 数字读取
 */
int digitalRead(GPIO_PinName pin)
{
    if (pin >= PIN_COUNT) return 0;
    const PinMap *p = &pin_map[pin];
    return (GPIO_ReadInputDataBit(p->port, p->pin) != RESET) ? 1 : 0;
}
/**
 * @brief 数字写
 */
void digitalWrite(GPIO_PinName pin, uint8_t value)
{
    if (pin >= PIN_COUNT || pin == GPIO_PIN_NONE) return;
    const PinMap *p = &pin_map[pin];
    if (value)
        GPIO_SetBits(p->port, p->pin);
    else
        GPIO_ResetBits(p->port, p->pin);
}

/**
 * @brief PWM 写（0~1000），对应 0.0% ~ 100.0% 占空比
 *        映射到 ARR=359 的 PWM 定时器（共 360 步）
 *        duty = 0   → CCR = 0     → 0.0%
 *        duty = 500 → CCR = 180   → ~50.0%
 *        duty = 1000 → CCR = 359  → 100.0%
 */
void analogWrite(GPIO_PinName pin, uint16_t duty)
{
    if (pin >= PIN_COUNT || !pin_map[pin].is_pwm) {
        return;
    }

    if (!pwm_initialized) {
        pwm_begin();
    }

    const PinMap *p = &pin_map[pin];

    if (duty > 1000) duty = 1000;

    uint16_t ccr_value;

    if (duty >= 1000) {
        ccr_value = 360;  // > ARR → 100%
    } else {
        ccr_value = (uint16_t)(duty * 0.36);
    }
    *(p->ccr) = ccr_value;
}
/**
 * @brief 初始化所有TIM3的 PWM 所需外设（只执行一次）
 */
void pwm_begin(void)
{
    if (pwm_initialized) return;
    pwm_initialized = 1;

    // ===== 1. 时钟使能 =====
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // ===== 2. GPIO 初始化（PWM 引脚）===== 
    // （其他 GPIO 可在 pinMode 中单独初始化）

    // ===== 3. TIM3 初始化 =====
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef        TIM_OCInitStructure;

    // 
    TIM_TimeBaseStructure.TIM_Period = 359; // 20kHz PWM
    TIM_TimeBaseStructure.TIM_Prescaler = 9; // 72MHz / 10 = 7.2MHz
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    // PWM 模式通用配置
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    // 启用所有映射到 TIM3 的 PWM 通道
    for (int i = 0; i < PIN_COUNT; i++) {
        if (pin_map[i].tim == TIM3) {
            TIM_OCInitStructure.TIM_Pulse = 0;  // 初始 0%
            if (pin_map[i].channel == TIM_Channel_3) {
                TIM_OC3Init(TIM3, &TIM_OCInitStructure);
            } else if (pin_map[i].channel == TIM_Channel_4) {
                TIM_OC4Init(TIM3, &TIM_OCInitStructure);
            }
        }
    }

    TIM_Cmd(TIM3, ENABLE);
}
